home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 251_01 / advprs.c < prev    next >
Text File  |  1987-10-27  |  7KB  |  331 lines

  1. /* advprs.c - adventure parser */
  2. /*
  3.     Copyright (c) 1986, by David Michael Betz
  4.     All rights reserved
  5. */
  6.  
  7. #include "advint.h"
  8. #include "advdbs.h"
  9.  
  10. /* parser result variables */
  11. int nouns[20];
  12. int *adjectives[20];
  13. static int actor,action,dobject,ndobjects,iobject;
  14. static int flag;
  15.  
  16. /* external routines */
  17. extern char *trm_get();
  18.  
  19. /* external variables */
  20. extern char line[];    /* line buffer */
  21.  
  22. /* local variables */
  23. static char *lptr;    /* line pointer */
  24. static int words[100];    /* word table */
  25. static char *wtext[100];/* word text table */
  26. static int *wptr;    /* word pointer */
  27. static int wcnt;    /* word count */
  28.  
  29. static int verbs[3];     /* words in the verb phrase */
  30. static int nnums[20];    /* noun word numbers */
  31. static int nptr;    /* noun pointer (actually, an index) */
  32. static int adjs[100];     /* adjective lists */
  33. static int anums[100];    /* adjective word numbers */
  34. static int aptr;    /* adjective pointer (actually, an index) */
  35.  
  36. /* parse - read and parse an input line */
  37. int parse()
  38. {
  39.     if (!parse1())
  40.     return (FALSE);
  41.     setvalue(V_ACTOR,actor);
  42.     setvalue(V_ACTION,action);
  43.     setvalue(V_DOBJECT,dobject);
  44.     setvalue(V_NDOBJECTS,ndobjects);
  45.     setvalue(V_IOBJECT,iobject);
  46.     return (TRUE);
  47. }
  48.  
  49. /* next - get the next command (next direct object) */
  50. int next()
  51. {
  52.     if (getvalue(V_NDOBJECTS) > 1) {
  53.     setvalue(V_ACTOR,actor);
  54.     setvalue(V_ACTION,action);
  55.     setvalue(V_DOBJECT,getvalue(V_DOBJECT) + 1);
  56.     setvalue(V_NDOBJECTS,getvalue(V_NDOBJECTS) - 1);
  57.     setvalue(V_IOBJECT,iobject);
  58.     return (TRUE);
  59.     }
  60.     else
  61.     return (FALSE);
  62. }
  63.  
  64. /* parse1 - the main parser */
  65. int parse1()
  66. {
  67.     int noun1,cnt1,noun2,cnt2;
  68.     int preposition,flag;
  69.  
  70.     /* initialize */
  71.     noun1 = noun2 = NIL; cnt1 = cnt2 = 0;
  72.     nptr = aptr = 0;
  73.     preposition = 0;
  74.     flag = 0;
  75.  
  76.     /* initialize the parser result variables */
  77.     actor = action = dobject = iobject = NIL;
  78.     ndobjects = 0;
  79.  
  80.     /* get an input line */
  81.     if (!get_line())
  82.     return (FALSE);
  83.  
  84.     /* check for actor */
  85.     if (wtype(*wptr) == WT_ADJECTIVE || wtype(*wptr) == WT_NOUN) {
  86.     if ((actor = getnoun()) == NIL)
  87.         return (FALSE);
  88.     flag |= A_ACTOR;
  89.     }
  90.  
  91.     /* get verb phrase */
  92.     if (!getverb())
  93.     return (FALSE);
  94.  
  95.     /* direct object, preposition and indirect object */
  96.     if (*wptr) {
  97.  
  98.     /* get the first set of noun phrases (direct objects) */
  99.     noun1 = nptr+1;
  100.     for (;;) {
  101.  
  102.             /* get the next direct object */
  103.             if (getnoun() == NIL)
  104.             return (FALSE);
  105.         ++cnt1;
  106.  
  107.         /* check for more direct objects */
  108.         if (*wptr == NIL || wtype(*wptr) != WT_CONJUNCTION)
  109.         break;
  110.         wptr++;
  111.     }
  112.  
  113.     /* get the preposition and indirect object */
  114.     if (*wptr) {
  115.  
  116.         /* get the preposition */
  117.         if (wtype(*wptr) == WT_PREPOSITION)
  118.         preposition = *wptr++;
  119.  
  120.         /* get the second set of noun phrases (indirect object) */
  121.         noun2 = nptr+1;
  122.         for (;;) {
  123.  
  124.             /* get the next direct object */
  125.             if (getnoun() == NIL)
  126.                 return (FALSE);
  127.         ++cnt2;
  128.  
  129.         /* check for more direct objects */
  130.         if (*wptr == NIL || wtype(*wptr) != WT_CONJUNCTION)
  131.             break;
  132.         wptr++;
  133.         }
  134.     }
  135.  
  136.     /* make sure this is the end of the sentence */
  137.     if (*wptr) {
  138.         parse_error();
  139.         return (FALSE);
  140.     }
  141.     }
  142.  
  143.     /* setup the direct and indirect objects */
  144.     if (preposition) {
  145.     if (cnt2 > 1) {
  146.         parse_error();
  147.         return (FALSE);
  148.     }
  149.     dobject = noun1;
  150.     ndobjects = cnt1;
  151.     iobject = noun2;
  152.     }
  153.     else if (noun2) {
  154.     if (cnt1 > 1) {
  155.         parse_error();
  156.         return (FALSE);
  157.     }
  158.     preposition = findword("to");
  159.     dobject = noun2;
  160.     ndobjects = cnt2;
  161.     iobject = noun1;
  162.     }
  163.     else {
  164.     dobject = noun1;
  165.     ndobjects = cnt1;
  166.     }
  167.  
  168.     /* setup the flags for the action lookup */
  169.     if (dobject) flag |= A_DOBJECT;
  170.     if (iobject) flag |= A_IOBJECT;
  171.  
  172.     /* find the action */
  173.     if ((action = findaction(verbs,preposition,flag)) == NIL) {
  174.     parse_error();
  175.     return (FALSE);
  176.     }
  177.  
  178.     /* return successfully */
  179.     return (TRUE);
  180. }
  181.  
  182. /* getverb - get a verb phrase and return the action it refers to */
  183. int getverb()
  184. {
  185.     /* get the verb */
  186.     if (*wptr == NIL || wtype(*wptr) != WT_VERB) {
  187.     parse_error();
  188.     return (NIL);
  189.     }
  190.     verbs[0] = *wptr++;
  191.     verbs[1] = NIL;
  192.  
  193.     /* check for a word following the verb */
  194.     if (*wptr) {
  195.     verbs[1] = *wptr;
  196.     verbs[2] = NIL;
  197.     if (checkverb(verbs))
  198.         wptr++;
  199.     else {
  200.         verbs[1] = words[wcnt-1];
  201.         if (checkverb(verbs))
  202.         words[--wcnt] = NIL;
  203.         else {
  204.         verbs[1] = NIL;
  205.         if (!checkverb(verbs)) {
  206.             parse_error();
  207.             return (NIL);
  208.         }
  209.         }
  210.     }
  211.     }
  212.     return (T);
  213. }
  214.  
  215. /* getnoun - get a noun phrase and return the object it refers to */
  216. int getnoun()
  217. {
  218.     /* initialize the adjective list pointer */
  219.     adjectives[nptr] = adjs + aptr;
  220.  
  221.     /* get the optional article */
  222.     if (*wptr != NIL && wtype(*wptr) == WT_ARTICLE)
  223.     wptr++;
  224.  
  225.     /* get optional adjectives */
  226.     while (*wptr != NIL && wtype(*wptr) == WT_ADJECTIVE) {
  227.     adjs[aptr] = *wptr++;
  228.     anums[aptr] = wptr - words - 1;
  229.     aptr++;
  230.     }
  231.     adjs[aptr++] = NULL;
  232.  
  233.     /* get the noun itself */
  234.     if (*wptr == NIL || wtype(*wptr) != WT_NOUN) {
  235.     parse_error();
  236.     return (NIL);
  237.     }
  238.  
  239.     /* save the noun */
  240.     nouns[nptr] = *wptr++;
  241.     nnums[nptr] = wptr - words - 1;
  242.     return (++nptr);
  243. }
  244.  
  245. /* get_line - get the input line and lookup each word */
  246. int get_line()
  247. {
  248.     /* read an input line */
  249.     trm_chr(':');
  250.     if ((lptr = trm_get(line)) == NULL) {
  251.     trm_str("Speak up!  I can't hear you!\n");
  252.     return (FALSE);
  253.     }
  254.  
  255.     /* get each word on the line */
  256.     for (wcnt = 0; skip_spaces(); wcnt++)
  257.     if (get_word() == NIL)
  258.         return (FALSE);
  259.     words[wcnt] = NIL;
  260.  
  261.     /* check for a blank line */
  262.     if (wcnt == 0) {
  263.     trm_str("Speak up!  I can't hear you!\n");
  264.     return (FALSE);
  265.     }
  266.  
  267.     /* point to the first word and return successfully */
  268.     wptr = words;
  269.     return (TRUE);
  270. }
  271.  
  272. /* skip_spaces - skip leading spaces */
  273. int skip_spaces()
  274. {
  275.     while (spacep(*lptr))
  276.     lptr++;
  277.     return (*lptr != EOS);
  278. }
  279.  
  280. /* show_noun - show a noun phrase */
  281. show_noun(n)
  282.   int n;
  283. {
  284.     int adj,*p;
  285.  
  286.     /* print the adjectives */
  287.     for (p = adjectives[n-1], adj = FALSE; *p; p++, adj = TRUE) {
  288.     if (adj) trm_chr(' ');
  289.     trm_str(wtext[anums[p-adjs]]);
  290.     }
  291.  
  292.     /* print the noun */
  293.     if (adj) trm_chr(' ');
  294.     trm_str(wtext[nnums[n-1]]);
  295. }
  296.  
  297. /* get_word - get the next word */
  298. int get_word()
  299. {
  300.     int ch;
  301.  
  302.     /* get the next word */
  303.     for (wtext[wcnt] = lptr; (ch = *lptr) != EOS && !spacep(ch); )
  304.     *lptr++ = (isupper(ch) ? tolower(ch) : ch);
  305.     if (*lptr != EOS) *lptr++ = EOS;
  306.  
  307.     /* look up the word */
  308.     if (words[wcnt] = findword(wtext[wcnt]))
  309.     return (words[wcnt]);
  310.     else {
  311.     trm_str("I don't know the word \"");
  312.     trm_str(wtext[wcnt]);
  313.     trm_str("\".\n");
  314.     return (NIL);
  315.     }
  316. }
  317.  
  318. /* spacep - is this character a space? */
  319. int spacep(ch)
  320.   int ch;
  321. {
  322.     return (ch == ' ' || ch == ',' || ch == '.');
  323. }
  324.  
  325. /* parse_error - announce a parsing error */
  326. parse_error()
  327. {
  328.     trm_str("I don't understand.\n");
  329. }
  330.  
  331.